home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-ppc-src / vlink / t_elf32.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  59KB  |  1,836 lines

  1. /* $VER: vlink t_elf32.c V0.6d (13.02.99)
  2.  *
  3.  * This file is part of vlink, a portable linker for multiple
  4.  * object formats.
  5.  * Copyright (c) 1997-99  Frank Wille
  6.  *
  7.  * vlink is freeware and part of the portable and retargetable ANSI C
  8.  * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
  9.  * vlink may be freely redistributed as long as no modifications are
  10.  * made and nothing is charged for it. Non-commercial usage is allowed
  11.  * without any restrictions.
  12.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  13.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  14.  *
  15.  *
  16.  * v0.6d (13.02.98) phx
  17.  *       The PowerUp ELF loader has its own constructor/destructor
  18.  *       functionality and wildly mixes all words in .ctors and .dtors.
  19.  *       Have to rename the sections to .ctor_/.dtor_ for elf32powerup
  20.  *       executable generation.
  21.  * v0.6c (05.02.98) phx
  22.  *       Constructor/destructor support for vbcc's _INIT/_EXIT
  23.  *       function. The function pointers will be placed into the
  24.  *       the .ctors and .dtors sections.
  25.  * v0.6a (19.12.98) phx
  26.  *       Support for little endian object file formats.
  27.  * v0.6  (24.10.98) phx
  28.  *       Standard ELF32 linker symbols _SDA_BASE_ and _SDA2_BASE_
  29.  *       are supported. _SDA_BASE_ points to .sdata+0x7ff0 (or .sbss, if
  30.  *       .sdata is missing) and _SDA2_BASE_ (EABI only) to .sdata2+0x7ff0.
  31.  *       Take base register section offset from FFFuncs.baseoff. Each
  32.  *       target defines their own offsets.
  33.  *       .sdata/.sbss and .sdata2/.sbss2 will always be combined.
  34.  *       Linking with shared objects is possible. Creating them is
  35.  *       a another story...
  36.  *       New target elf32powerup. It is a elf32ppcbe-type target, which
  37.  *       uses relocatable objects as final executables. It is used for
  38.  *       the Amiga PowerUp turbo boards from Phase5, which have a special
  39.  *       ELF object loader. This loader will do some kind of dynamic
  40.  *       linking with functions from the PowerUp kernel.
  41.  *       _LinkerDB is no longer known to elf32ppcbe, but only to
  42.  *       elf32powerup.
  43.  * v0.5d (22.08.98) phx
  44.  *       Faster memory allocation can be activated by #define FASTALLOC.
  45.  * v0.5b (05.07.98) phx
  46.  *       Linker symbol _LinkerDB for elf32ppcbe. _LinkerDB is a reloc sym-
  47.  *       bol, which can be used to initialize a small data base register.
  48.  * v0.5  (27.06.98) phx
  49.  *       Target-specific linker symbol support: elf32_lnksym(),
  50.  *       elf32_setlnksym().
  51.  * v0.4  (05.06.98) phx
  52.  *       New FFF targetlink(). Currently no meaning for ELF.
  53.  * v0.3b (25.04.98) phx
  54.  *       Renamed from t_elf.c into t_elf32.c.
  55.  * v0.3  (17.04.98) phx
  56.  *       First version, which links and writes ELF PowerPC 32Bit big
  57.  *       endian objects (elf32ppcbe) reliable.
  58.  * v0.0  (21.03.98) phx
  59.  *       File created.
  60.  */
  61.  
  62.  
  63. #if defined(ELF32_PPC_BE) || defined(ELF32_PPC_LE) || defined(ELF32_POWERUP)
  64. #define T_ELF32_C
  65. #include "vlink.h"
  66. #include "elf32.h"
  67. #include "rel_elfppc.h"
  68.  
  69. #define ELF_VER 1
  70.  
  71.  
  72. #if defined(ELF32_PPC_BE) || defined(ELF32_POWERUP)
  73. static int ppc32be_identify(char*,uint8 *,unsigned long);
  74. static void ppc32be_readconv(struct GlobalVars *,struct LinkFile *);
  75. static void ppc32be_readELF(struct GlobalVars *,struct LinkFile *,uint8 *);
  76. static unsigned long ppc32be_secbase(struct GlobalVars *,char *);
  77. static uint8 ppc32be_cmpsecflags(uint8,uint8);
  78. static struct Section *ppc32be_bssdefault(struct ObjectUnit *);
  79. static int ppc32be_targetlink(struct GlobalVars *,struct LinkedSection *,
  80.                               struct Section *);
  81. static struct Symbol *ppc32be_lnksym(struct GlobalVars *,struct Section *,
  82.                                      struct XReference *);
  83. static void ppc32be_setlnksym(struct GlobalVars *,struct Symbol *,
  84.                               struct XReference *);
  85. static void ppc32be_relocs(struct GlobalVars *,uint8 *,struct ObjectUnit *,
  86.                            struct Elf32_Shdr *);
  87. #endif
  88. #ifdef ELF32_PPC_BE
  89. static void ppc32be_writeobject(struct GlobalVars *,FILE *);
  90. static void ppc32be_writeshared(struct GlobalVars *,FILE *);
  91. static void ppc32be_writeexec(struct GlobalVars *,FILE *);
  92. static uint8 ppc32be_getrel(uint8,char *,uint32);
  93.  
  94. struct FFFuncs fff_elf32ppcbe = {
  95.   "elf32ppcbe",
  96.   ppc32be_identify,
  97.   ppc32be_readconv,
  98.   ppc32be_secbase,
  99.   ppc32be_cmpsecflags,
  100.   ppc32be_bssdefault,
  101.   ppc32be_targetlink,
  102.   ppc32be_lnksym,
  103.   ppc32be_setlnksym,
  104.   ppc32be_writeobject,
  105.   ppc32be_writeshared,
  106.   ppc32be_writeexec,
  107.   0x7ff0,
  108.   NULL,
  109.   1 /* big endian */
  110. };
  111. #endif
  112.  
  113.  
  114. #ifdef ELF32_POWERUP
  115. static struct Symbol *powerup_lnksym(struct GlobalVars *,struct Section *,
  116.                                      struct XReference *);
  117. static void powerup_setlnksym(struct GlobalVars *,struct Symbol *,
  118.                               struct XReference *);
  119. static void powerup_writeobject(struct GlobalVars *,FILE *);
  120. static void powerup_writeshared(struct GlobalVars *,FILE *);
  121. static void powerup_writeexec(struct GlobalVars *,FILE *);
  122. static uint8 powerup_getrel(uint8,char *,uint32);
  123.  
  124. struct FFFuncs fff_elf32powerup = {
  125.   "elf32powerup",
  126.   ppc32be_identify,
  127.   ppc32be_readconv,
  128.   ppc32be_secbase,
  129.   ppc32be_cmpsecflags,
  130.   ppc32be_bssdefault,
  131.   ppc32be_targetlink,
  132.   powerup_lnksym,
  133.   powerup_setlnksym,
  134.   powerup_writeobject,
  135.   powerup_writeshared,
  136.   powerup_writeexec,
  137.   0x7ff0,
  138.   NULL,
  139.   1 /* big endian */
  140. };
  141.  
  142.  
  143. /* elf32powerup linker symbols */
  144. static char *linkerdb = "_LinkerDB";
  145. #define LINKERDB        0   /* _LinkerDB, powerup */
  146. #endif
  147.  
  148.  
  149. /* elf32 common linker symbols */
  150. static char *elf32_symnames[] = {
  151.   "_SDA_BASE_","_SDA2_BASE_",".ctors",".dtors"
  152. };
  153. /* number of elf32 linker symbols */
  154. #define ELF32_LNKSYMS 4
  155.  
  156. /* Linker symbol IDs */
  157. #define SDABASE         0   /* _SDA_BASE_, elf32 */
  158. #define SDA2BASE        1   /* _SDA2_BASE_, elf32 */
  159. #define CTORS           2   /* .ctors */
  160. #define DTORS           3   /* .dtors */
  161.  
  162. /* small data sections */
  163. static char *sdata = ".sdata";
  164. static char *sbss = ".sbss";
  165. static char *sdata2 = ".sdata2";
  166. static char *sbss2 = ".sbss2";
  167.  
  168. /* automatic constructors and destructors (vbcc) */
  169. static char vbcc_INIT[] = "_INIT";
  170. static char vbcc_EXIT[] = "_EXIT";
  171. static char xtors_objname[] = "INITEXIT"; /* unit name for con/destructors */
  172.  
  173.  
  174. static int elf32be_identify(struct FFFuncs *,char *,struct Elf32_Ehdr *,
  175.                             unsigned long,unsigned char,unsigned char,
  176.                             uint16,uint32);
  177. static void elf32be_check_ar_type(struct FFFuncs *,char *,
  178.                                   struct Elf32_Ehdr *,unsigned char,
  179.                                   unsigned char,uint32,uint16,uint16,uint16);
  180. static char *elf32be_shstrtab(struct LinkFile *,struct Elf32_Ehdr *);
  181. static char *elf32be_strtab(struct LinkFile *,struct Elf32_Ehdr *,int);
  182. static struct Elf32_Sym *elf32be_symtab(struct LinkFile *,
  183.                                         struct Elf32_Ehdr *,int);
  184. static struct Elf32_Shdr *elf32be_shdr(struct LinkFile *lf,
  185.                                        struct Elf32_Ehdr *,uint16);
  186. static void elf32be_section(uint8 *,struct ObjectUnit *,
  187.                             struct Elf32_Shdr *,int);
  188. static int get_xtors_pri(char *);
  189. static void elf32be_symbols(struct GlobalVars *,uint8 *,struct ObjectUnit *,
  190.                             struct Elf32_Shdr *);
  191. static void elf32be_reloc(struct GlobalVars *,struct Elf32_Ehdr *,
  192.                           struct Section *,uint32,struct Elf32_Rela *,
  193.                           bool,uint8);
  194. static struct Section *elf32be_bssdefault(struct ObjectUnit *);
  195. static int elf32_targetlink(struct GlobalVars *,struct LinkedSection *,
  196.                             struct Section *);
  197. static struct Symbol *elf32_lnksym(struct GlobalVars *,struct Section *,
  198.                                    struct XReference *,struct FFFuncs *);
  199. static void elf32_setlnksym(struct GlobalVars *,struct Symbol *,
  200.                             struct XReference *,struct FFFuncs *);
  201. static void elf32be_header(FILE *,uint16,uint16,uint32,uint32,uint32,
  202.                            uint32,uint16,uint16,uint16);
  203. static void elf32be_writeshdrs(FILE *,uint32,uint32);
  204. static void elf32be_stdsymtab(struct GlobalVars *,uint8,uint8);
  205. static void elf32be_addsymlist(struct GlobalVars *,struct SymTabList *,
  206.                                uint8,uint8);
  207. static void elf32be_makeshdrs(struct GlobalVars *);
  208. static void elf32be_addrelocs(struct GlobalVars *,
  209.                               uint8 (*)(uint8,char *,uint32));
  210. static void elf32be_makeshstrtab(void);
  211. static void elf32be_makestrtab(void);
  212. static void elf32be_makesymtab(uint32);
  213. static struct ShdrNode *elf32be_addshdr(uint32,uint32,uint32,uint32,uint32,
  214.                                         uint32,uint32,uint32,uint32,uint32);
  215. static uint32 elf32be_addsym(struct SymTabList *,char *,uint32,uint32,
  216.                              uint8,uint8,uint16);
  217. static uint32 elf32be_findsym(struct SymTabList *,char *,uint16);
  218. static void elf32be_addrela(uint32,int32,uint32,uint8);
  219.  
  220. static void elf32_initlists(void);
  221. static struct ShdrNode *elf32_newshdr(void);
  222. static uint32 elf32_addshdrstr(char *);
  223. static uint32 elf32_addstr(char *);
  224. static uint32 elf32_addstrlist(struct StrTabList *,char *);
  225. static uint8 elf32_getinfo(struct Symbol *);
  226. static uint8 elf32_getbind(struct Symbol *);
  227. static uint16 elf32_getshndx(struct Symbol *,uint8);
  228. static void elf32_writesections(struct GlobalVars *,FILE *);
  229. static void elf32_writestrtab(FILE *,struct StrTabList *);
  230. static void elf32_writesymtab(FILE *,struct SymTabList *);
  231. static void elf32_writerelocs(struct GlobalVars *,FILE *);
  232.  
  233.  
  234. static char ELFid[4] = {   /* identification for all ELF files */
  235.   0x7f,'E','L','F'
  236. };
  237.  
  238. static struct ar_info ai;  /* for scanning library archives */
  239. static char *shstrtab;     /* section header string table */
  240. static char *nullstr = "";
  241.  
  242. /* static data required for output file generation */
  243. static struct list shdrlist;
  244. static struct list phdrlist;
  245. static struct list relalist;
  246. static struct SymTabList symlist;
  247. static struct StrTabList shstrlist;
  248. static struct StrTabList stringlist;
  249. static uint32 shdrindex;
  250. static uint32 symtabidx,shstrtabidx,strtabidx; /* indexes of Shdr names */
  251. static uint32 elfoffset;    /* current ELF file offset */
  252. static int secsyms;         /* offset to find section symbols by shndx */
  253.  
  254.  
  255.  
  256. /*****************************************************************/
  257. /*                          Read ELF                             */
  258. /*****************************************************************/
  259.  
  260.  
  261. #if defined(ELF32_PPC_BE) || defined(ELF32_POWERUP)
  262.  
  263. static int ppc32be_identify(char *name,uint8 *p,unsigned long plen)
  264. /* identify ELF-PPC-32Bit-BigEndian */
  265. {
  266.   int id;
  267.  
  268.   /* first check for ancient PowerPC machine types */
  269.   if ((id = elf32be_identify(&fff_elf32ppcbe,name,(struct Elf32_Ehdr *)p,
  270.                              plen,ELFCLASS32,ELFDATA2MSB,EM_CYGNUS_POWERPC,
  271.                              ELF_VER)) != ID_UNKNOWN)
  272.     return (id);
  273.  
  274.   /* EM_PPC_OLD is used in Motorola's libmoto.a, for example... */
  275.   if ((id = elf32be_identify(&fff_elf32ppcbe,name,(struct Elf32_Ehdr *)p,
  276.                              plen,ELFCLASS32,ELFDATA2MSB,EM_PPC_OLD,
  277.                              ELF_VER)) != ID_UNKNOWN)
  278.     return (id);
  279.  
  280.   /* the normal case: EM_PPC */
  281.   return (elf32be_identify(&fff_elf32ppcbe,name,(struct Elf32_Ehdr *)p,plen,
  282.                            ELFCLASS32,ELFDATA2MSB,EM_PPC,ELF_VER));
  283. }
  284.  
  285.  
  286. static void ppc32be_readconv(struct GlobalVars *gv,struct LinkFile *lf)
  287. /* Read elfppc32be executable / object / shared obj. */
  288. {
  289.   if (lf->type == ID_LIBARCH) {
  290.     if (ar_init(&ai,(char *)lf->data,lf->length,lf->filename)) {
  291.       while (ar_extract(&ai)) {
  292.         lf->objname = allocstring(ai.name);
  293.         ppc32be_readELF(gv,lf,ai.data);
  294.       }
  295.     }
  296.     else
  297.       ierror("ppc32be_readconv(): archive %s corrupted since last access",
  298.              lf->pathname);
  299.   }
  300.   else {
  301.     lf->objname = lf->filename;
  302.     ppc32be_readELF(gv,lf,lf->data);
  303.   }
  304. }
  305.  
  306.  
  307. static void ppc32be_readELF(struct GlobalVars *gv,struct LinkFile *lf,
  308.                             uint8 *elf)
  309. {
  310.   struct ObjectUnit *u;
  311.   struct Elf32_Ehdr *ehdr = (struct Elf32_Ehdr *)elf;
  312.   struct Elf32_Shdr *shdr;
  313.   uint16 i,num_shdr;
  314.  
  315.   if (lf->type == ID_LIBARCH)  /* check ar-member for correct format */
  316.     elf32be_check_ar_type(&fff_elf32ppcbe,lf->pathname,ehdr,
  317.                           ELFCLASS32,ELFDATA2MSB,ELF_VER,
  318.                           EM_PPC,EM_PPC_OLD,EM_CYGNUS_POWERPC);
  319.  
  320.   shstrtab = elf32be_shstrtab(lf,ehdr);
  321.   u = create_objunit(lf,lf->objname);
  322.  
  323.   switch (read16be(ehdr->e_type)) {
  324.  
  325.     case ET_REL:  /* relocatable object file */
  326.       if (read16be(ehdr->e_phnum) > 0)
  327.         error(47,lf->pathname,lf->objname);  /* ignoring program hdr. tab */
  328.       num_shdr = read16be(ehdr->e_shnum);
  329.  
  330.       /* create vlink sections */
  331.       for (i=1; i<num_shdr; i++) {
  332.         shdr = elf32be_shdr(lf,ehdr,i);
  333.         switch (read32be(shdr->sh_type)) {
  334.           case SHT_PROGBITS:
  335.           case SHT_NOBITS:
  336.             elf32be_section(elf,u,shdr,i);  /* create a new section */
  337.           default:
  338.             break;
  339.         }
  340.       }
  341.  
  342.       /* parse the other section headers */
  343.       for (i=1; i<num_shdr; i++) {
  344.         shdr = elf32be_shdr(lf,ehdr,i);
  345.         switch (read32be(shdr->sh_type)) {
  346.           case SHT_NULL:
  347.           case SHT_STRTAB:
  348.           case SHT_PROGBITS:
  349.           case SHT_NOBITS:
  350.             break;
  351.           case SHT_SYMTAB:
  352.             elf32be_symbols(gv,elf,u,shdr);  /* symbol definitions */
  353.             break;
  354.           case SHT_REL:
  355.           case SHT_RELA:
  356.             ppc32be_relocs(gv,elf,u,shdr);  /* relocation information */
  357.             break;
  358.           case SHT_NOTE:
  359.             ierror("ppc32be_readELF(): %s: Section header type %d is "
  360.                    "currently not supported",lf->pathname,
  361.                    (int)read32be(shdr->sh_type));
  362.             break;
  363.           default:
  364.             /* section header type not needed in relocatable objects */
  365.             error(48,lf->pathname,read32be(shdr->sh_type),lf->objname);
  366.             break;
  367.         }
  368.       }
  369.       break;
  370.  
  371.  
  372.     case ET_DYN:  /* shared object file */
  373.       num_shdr = read16be(ehdr->e_shnum);
  374.  
  375.       /* create vlink sections */
  376.       for (i=1; i<num_shdr; i++) {
  377.         shdr = elf32be_shdr(lf,ehdr,i);
  378.         switch (read32be(shdr->sh_type)) {
  379.           case SHT_PROGBITS:
  380.           case SHT_NOBITS:
  381.             elf32be_section(elf,u,shdr,i);  /* create a new section */
  382.           default:
  383.             break;
  384.         }
  385.       }
  386.  
  387.       /* parse the other section headers */
  388.       for (i=1; i<num_shdr; i++) {
  389.         shdr = elf32be_shdr(lf,ehdr,i);
  390.         switch (read32be(shdr->sh_type)) {
  391.           case SHT_NULL:
  392.           case SHT_STRTAB:
  393.           case SHT_PROGBITS:
  394.           case SHT_NOBITS:
  395.           case SHT_HASH:
  396.           case SHT_DYNAMIC:
  397.           case SHT_DYNSYM:
  398.             break;
  399.           case SHT_SYMTAB:
  400.             elf32be_symbols(gv,elf,u,shdr);  /* symbol definitions */
  401.             break;
  402.           case SHT_NOTE:
  403.             ierror("ppc32be_readELF(): %s: Section header type %d is "
  404.                    "currently not supported",lf->pathname,
  405.                    (int)read32be(shdr->sh_type));
  406.             break;
  407.           default:
  408.             /* section header type not needed in shared objects */
  409.             error(60,lf->pathname,read32be(shdr->sh_type),lf->objname);
  410.             break;
  411.         }
  412.       }
  413.       break;
  414.  
  415.  
  416.     case ET_EXEC: /* executable file */
  417.       /* @@@ */
  418.       ierror("ppc32be_readELF(): %s: Executables are currently "
  419.              "not supported",lf->pathname);
  420.       break;
  421.  
  422.  
  423.     default:
  424.       error(41,lf->pathname,lf->objname);  /* illegal fmt./file corrupted */
  425.       break;
  426.   }
  427.  
  428.   /* add new object unit to the appropriate list */
  429.   add_objunit(gv,u,FALSE);
  430. }
  431.  
  432.  
  433. static unsigned long ppc32be_secbase(struct GlobalVars *gv,char *name)
  434. /* return default base address for a section with this name */
  435. {
  436.   return (0);  /* @@@ has to be fixed... */
  437. }
  438.  
  439.  
  440. static uint8 ppc32be_cmpsecflags(uint8 oldflags,uint8 newflags)
  441. /* compare and verify target-specific section flags, */
  442. /* return 0xff if sections are incompatible, otherwise return new flags */
  443. {
  444.   return (oldflags|newflags);
  445. }
  446.  
  447.  
  448. static struct Section *ppc32be_bssdefault(struct ObjectUnit *ou)
  449. /* Create a default BSS section for elfppc32be */
  450. {
  451.   return (elf32be_bssdefault(ou));
  452. }
  453.  
  454.  
  455. static int ppc32be_targetlink(struct GlobalVars *gv,struct LinkedSection *ls,
  456.                               struct Section *s)
  457. /* returns 1, if target requires the combination of the two sections, */
  458. /* returns -1, if target don't want to combine them, */
  459. /* returns 0, if target doesn't care - standard linking rules are used. */
  460. {
  461.   return (elf32_targetlink(gv,ls,s));
  462. }
  463.  
  464.  
  465. static struct Symbol *ppc32be_lnksym(struct GlobalVars *gv,
  466.                                      struct Section *sec,
  467.                                      struct XReference *xref)
  468. {
  469.   return (elf32_lnksym(gv,sec,xref,&fff_elf32ppcbe));
  470. }
  471.  
  472.  
  473. static void ppc32be_setlnksym(struct GlobalVars *gv,struct Symbol *xdef,
  474.                               struct XReference *xref)
  475. {
  476.   elf32_setlnksym(gv,xdef,xref,&fff_elf32ppcbe);
  477. }
  478.  
  479.  
  480. static void ppc32be_relocs(struct GlobalVars *gv,uint8 *elf,
  481.                            struct ObjectUnit *ou,struct Elf32_Shdr *shdr)
  482. {
  483.   char *sec_name = shstrtab + read32be(shdr->sh_name);
  484.   struct LinkFile *lf = ou->lnkfile;
  485.   bool rela = read32be(shdr->sh_type) == SHT_RELA;
  486.   uint8 rtype,*data = elf + read32be(shdr->sh_offset);
  487.   unsigned long entsize = read32be(shdr->sh_entsize);
  488.   int nrelocs = (int)(read32be(shdr->sh_size) / (uint32)entsize);
  489.   uint32 symndx = read32be(shdr->sh_link);
  490.  
  491.   struct Section *s;
  492.  
  493.   if ((data < lf->data) || 
  494.       (data + read32be(shdr->sh_size) > lf->data + lf->length))
  495.     error(51,lf->pathname,"ppc32be reloc",lf->objname);  /* illegal offset */
  496.   if (!(s = find_sect_id(ou,read32be(shdr->sh_info))))
  497.     /* a section with this index doesn't exist! */
  498.     error(52,lf->pathname,sec_name,lf->objname,(int)read32be(shdr->sh_info));
  499.  
  500.   while (nrelocs--) {
  501.     rtype = R_NONE;
  502.     switch (ELF32_R_TYPE(read32be(((struct Elf32_Rela *)data)->r_info))) {
  503.       case R_NONE:
  504.         break;  /* ignore */
  505.       case R_PPC_ADDR32:
  506.         rtype = R_ADDR32;
  507.         break;
  508.       case R_PPC_ADDR24:
  509.         rtype = R_ADDR26;
  510.         break;
  511.       case R_PPC_ADDR16:
  512.         rtype = R_ADDR16;
  513.         break;
  514.       case R_PPC_ADDR16_LO:
  515.         rtype = R_ADDR16_LO;
  516.         break;
  517.       case R_PPC_ADDR16_HI:
  518.         rtype = R_ADDR16_HI;
  519.         break;
  520.       case R_PPC_ADDR16_HA:
  521.         rtype = R_ADDR16_HA;
  522.         break;
  523.       case R_PPC_ADDR14:
  524.         rtype = R_ADDR14;
  525.         break;
  526.       case R_PPC_ADDR14_BRTAKEN:
  527.         rtype = R_ADDR14_BRTAKEN;
  528.         break;
  529.       case R_PPC_ADDR14_BRNTAKEN:
  530.         rtype = R_ADDR14_BRNTAKEN;
  531.         break;
  532.       case R_PPC_REL24:
  533.         rtype = R_REL26;
  534.         break;
  535.       case R_PPC_REL14:
  536.         rtype = R_REL14;
  537.         break;
  538.       case R_PPC_REL14_BRTAKEN:
  539.         rtype = R_REL14_BRTAKEN;
  540.         break;
  541.       case R_PPC_REL14_BRNTAKEN:
  542.         rtype = R_REL14_BRNTAKEN;
  543.         break;
  544.       case R_PPC_REL32:
  545.         rtype = R_REL32;
  546.         break;
  547.       case R_PPC_SDAREL16:
  548.         rtype = R_BASEREL16;
  549.         break;
  550.       case R_PPC_PASM_TOC16:
  551.         rtype = R_BASEREL16;
  552.         break;
  553.       default:
  554.         ierror("ppc32be_relocs(): %s (%s): Reloc type %d in %s is currently "
  555.                "not supported",lf->pathname,lf->objname,
  556.                ELF32_R_TYPE(read32be(((struct Elf32_Rela *)data)->r_info)),
  557.                sec_name);
  558.         break;
  559.     }
  560.  
  561.     if (rtype > R_NONE)
  562.       elf32be_reloc(gv,(struct Elf32_Ehdr *)elf,s,symndx,
  563.                     (struct Elf32_Rela *)data,rela,rtype);
  564.     data += entsize;  /* next reloc */
  565.   }
  566.  
  567. }
  568.  
  569. #endif /* ELF32_PPC_BE || ELF32_POWERUP */
  570.  
  571.  
  572. #ifdef ELF32_POWERUP
  573.  
  574. static struct Symbol *powerup_lnksym(struct GlobalVars *gv,
  575.                                      struct Section *sec,
  576.                                      struct XReference *xref)
  577. {
  578.   struct Symbol *sym;
  579.  
  580.   if (sym = findlnksymbol(&fff_elf32powerup,xref->name))
  581.     return (sym);
  582.  
  583.   if (!gv->dest_object) {
  584.     if (!strcmp(linkerdb,xref->name)) {  /* _LinkerDB */
  585.       sym = addlnksymbol(&fff_elf32powerup,NULL,linkerdb,
  586.                          fff_elf32powerup.baseoff,SYM_RELOC,
  587.                          SYMF_LNKSYM,SYMI_OBJECT,SYMB_GLOBAL,0);
  588.       sym->extra = SYMX_SPECIAL|LINKERDB;
  589.       return (sym);  /* new linker symbol created */
  590.     }
  591.   }
  592.  
  593.   return (ppc32be_lnksym(gv,sec,xref));
  594. }
  595.  
  596.  
  597. static void powerup_setlnksym(struct GlobalVars *gv,struct Symbol *xdef,
  598.                               struct XReference *xref)
  599. {
  600.   if ((xdef->flags & SYMF_LNKSYM) && (xdef->extra & SYMX_SPECIAL)) {
  601.     struct LinkedSection *sdsec = smalldata_section(gv);
  602.  
  603.     /* currently, there is only _LinkerDB... set small data section */
  604.     xdef->relsect = (struct Section *)sdsec->sections.first;
  605.  
  606.     xdef->flags &= ~SYMF_LNKSYM;  /* do not init again */
  607.   }
  608.   else
  609.     ppc32be_setlnksym(gv,xdef,xref);
  610. }
  611.  
  612. #endif /* ELF32_POWERUP */
  613.  
  614.  
  615. static int elf32be_identify(struct FFFuncs *ff,char *name,
  616.                             struct Elf32_Ehdr *p,unsigned long plen,
  617.                             unsigned char class,unsigned char endian,
  618.                             uint16 machine,uint32 ver)
  619. /* check a possible ELF file against the requirements, then */
  620. /* return its type (object, library, shared object) */
  621. {
  622.   bool arflag = FALSE;
  623.  
  624.   if (plen < sizeof(struct Elf32_Ehdr))
  625.     return (ID_UNKNOWN);
  626.  
  627.   if (ar_init(&ai,(char *)p,plen,name)) {
  628.     /* library archive detected, extract 1st archive member */
  629.     arflag = TRUE;
  630.     if (!(ar_extract(&ai))) {
  631.       error(38,name);  /* Empty archive ignored */
  632.       return (ID_LIBARCH);
  633.     }
  634.     p = (struct Elf32_Ehdr *)ai.data;
  635.   }
  636.  
  637.   if (!strncmp(p->e_ident,ELFid,4)) {
  638.     /* ELF identification found */
  639.     if (p->e_ident[EI_CLASS]==class && p->e_ident[EI_DATA]==endian &&
  640.         p->e_ident[EI_VERSION]==(unsigned char)ver &&
  641.         read32be(p->e_version)==ver && read16be(p->e_machine)==machine) {
  642.       switch (read16be(p->e_type)) {
  643.         case ET_REL:
  644.           return (arflag ? ID_LIBARCH : ID_OBJECT);
  645.         case ET_EXEC:
  646.           if (arflag) /* no executables in library archives */
  647.             error(40,name,ff->tname);
  648.           return (ID_EXECUTABLE);
  649.         case ET_DYN:
  650.           if (arflag) /* no shared objects in library archives */
  651.             error(39,name,ff->tname);
  652.           return (ID_SHAREDOBJ);
  653.         default:
  654.           error(41,name,ff->tname);  /* illegal fmt. / file corrupted */
  655.           break;
  656.       }
  657.     }
  658.   }
  659.  
  660.   return (ID_UNKNOWN);
  661. }
  662.  
  663.  
  664. static void elf32be_check_ar_type(struct FFFuncs *ff,char *name,
  665.                                   struct Elf32_Ehdr *ehdr,unsigned char class,
  666.                                   unsigned char endian,uint32 ver,
  667.                                   uint16 mach1,uint16 mach2,uint16 mach3)
  668. /* check all library archive members before conversion */
  669. {
  670.   uint16 m = read16be(ehdr->e_machine);
  671.  
  672.   if (!strncmp(ehdr->e_ident,ELFid,4)) {
  673.     /* ELF identification found */
  674.     if (ehdr->e_ident[EI_CLASS]==class && ehdr->e_ident[EI_DATA]==endian &&
  675.         ehdr->e_ident[EI_VERSION]==(unsigned char)ver &&
  676.         read32be(ehdr->e_version)==ver && (m==mach1 || m==mach2 || m==mach3)) {
  677.       switch (read16be(ehdr->e_type)) {
  678.         case ET_REL:
  679.           return;
  680.         case ET_EXEC:  /* no executables in library archives */
  681.           error(40,name,ff->tname);
  682.           break;
  683.         case ET_DYN:  /* no shared objects in library archives */
  684.           error(39,name,ff->tname);
  685.           break;
  686.         default:  /* illegal fmt. / file corrupted */
  687.           break;
  688.       }
  689.     }
  690.   }
  691.   error(41,name,ff->tname);
  692. }
  693.  
  694.  
  695. static char *elf32be_shstrtab(struct LinkFile *lf,struct Elf32_Ehdr *ehdr)
  696. /* returns a pointer to the section header string table, if present, */
  697. /* or NULL, otherwise */
  698. {
  699.   uint16 i;
  700.   struct Elf32_Shdr *shdr;
  701.   char *stab;
  702.  
  703.   if (i = read16be(ehdr->e_shstrndx)) {
  704.     shdr = elf32be_shdr(lf,ehdr,i);
  705.     if (read32be(shdr->sh_type) != SHT_STRTAB)
  706.       error(45,lf->pathname,lf->objname);  /* illegal type */
  707.     stab = ((char *)ehdr) + read32be(shdr->sh_offset);
  708.     if (((uint8 *)stab < lf->data) || 
  709.         ((uint8 *)stab + read32be(shdr->sh_size) > lf->data + lf->length))
  710.       error(46,lf->pathname,lf->objname);  /* illegal offset */
  711.     else
  712.       return (stab);
  713.   }
  714.   return (NULL);
  715. }
  716.  
  717.  
  718. static char *elf32be_strtab(struct LinkFile *lf,
  719.                             struct Elf32_Ehdr *ehdr,int idx)
  720. /* returns a pointer to the string table */
  721. {
  722.   static char *tabname = "string";
  723.   struct Elf32_Shdr *shdr;
  724.   char *stab;
  725.  
  726.   shdr = elf32be_shdr(lf,ehdr,idx);
  727.   if (read32be(shdr->sh_type) != SHT_STRTAB)
  728.      error(50,lf->pathname,tabname,lf->objname);  /* illegal type */
  729.   stab = ((char *)ehdr) + read32be(shdr->sh_offset);
  730.   if (((uint8 *)stab < lf->data) || 
  731.       ((uint8 *)stab + read32be(shdr->sh_size) > lf->data + lf->length))
  732.     error(51,lf->pathname,tabname,lf->objname);  /* illegal offset */
  733.   return (stab);
  734. }
  735.  
  736.  
  737. static struct Elf32_Sym *elf32be_symtab(struct LinkFile *lf,
  738.                                         struct Elf32_Ehdr *ehdr,int idx)
  739. /* returns a pointer to the symbol table */
  740. {
  741.   static char *tabname = "symbol";
  742.   struct Elf32_Shdr *shdr;
  743.   struct Elf32_Sym *symtab;
  744.  
  745.   shdr = elf32be_shdr(lf,ehdr,idx);
  746.   if (read32be(shdr->sh_type) != SHT_SYMTAB)
  747.      error(50,lf->pathname,tabname,lf->objname);  /* illegal type */
  748.   symtab = (struct Elf32_Sym *)((uint8 *)ehdr + read32be(shdr->sh_offset));
  749.   if (((uint8 *)symtab < lf->data) || 
  750.       ((uint8 *)symtab + read32be(shdr->sh_size) > lf->data + lf->length))
  751.     error(51,lf->pathname,tabname,lf->objname);  /* illegal offset */
  752.   return (symtab);
  753. }
  754.  
  755.  
  756. static struct Elf32_Shdr *elf32be_shdr(struct LinkFile *lf,
  757.                                        struct Elf32_Ehdr *ehdr,uint16 idx)
  758. /* return pointer to section header #idx */
  759. {
  760.   struct Elf32_Shdr *shdr;
  761.  
  762.   if (idx < read16be(ehdr->e_shnum)) {
  763.     shdr = (struct Elf32_Shdr *)(((char *)ehdr) + ((read32be(ehdr->e_shoff) +
  764.            (uint32)read16be(ehdr->e_shentsize) * (uint32)idx)));
  765.     if (((uint8 *)shdr < lf->data) ||
  766.         (((uint8 *)shdr)+read16be(ehdr->e_shentsize) > lf->data+lf->length))
  767.       /* section header #x has illegal offset */
  768.       error(44,lf->pathname,(int)idx,lf->objname);
  769.     return (shdr);
  770.   }
  771.   else  /* Invalid ELF section header index */
  772.     error(43,lf->pathname,(int)idx,lf->objname);
  773.   return (NULL);  /* not reached, for compiler's sake */
  774. }
  775.  
  776.  
  777. static void elf32be_section(uint8 *elf,struct ObjectUnit *ou,
  778.                             struct Elf32_Shdr *shdr,int shndx)
  779. /* create a new section */
  780. {
  781.   char *sec_name = shstrtab + read32be(shdr->sh_name);
  782.   uint8 *data = elf + read32be(shdr->sh_offset);
  783.   unsigned long size = (unsigned long)read32be(shdr->sh_size);
  784.   uint32 f = read32be(shdr->sh_flags);
  785.   struct LinkFile *lf = ou->lnkfile;
  786.   uint8 type=ST_DATA,flags=0;
  787.   struct Section *s;
  788.  
  789.   if (read32be(shdr->sh_type) == SHT_NOBITS) {
  790.     data = NULL;
  791.     type = ST_UDATA;
  792.     flags |= SF_UNINITIALIZED;
  793.   }
  794.   else {
  795.     if (data+size > lf->data+lf->length)  /* illegal section offset */
  796.       error(49,lf->pathname,sec_name,lf->objname);
  797.   }
  798.   s = create_section(ou,sec_name,data,size);
  799.  
  800.   s->id = shndx;  /* use section header index for identification */
  801.   s->protection = SP_READ;
  802.   if ((f & SHF_EXECINSTR) && data) {
  803.     type = ST_CODE;
  804.     s->protection |= SP_EXEC;
  805.   }
  806.   if (f & SHF_WRITE)
  807.     s->protection |= SP_WRITE;
  808.   if (!(f & SHF_ALLOC))
  809.     flags |= SF_DISCARD;
  810.  
  811.   s->type = type;
  812.   s->flags = flags;
  813.   s->alignment = (uint8)shiftval(read32be(shdr->sh_addralign));
  814.   addtail(&ou->sections,&s->n);  /* add Section to ObjectUnit */
  815. }
  816.  
  817.  
  818. static int get_xtors_pri(char *s)
  819. /* Return priority of a constructor/destructor function name. */
  820. /* Its priority may be specified by a number behind the 2nd underscore. */
  821. /* Example: __INIT_9_OpenLibs (constructor with priority 9) */
  822. {
  823.   if (*s++ == '_')
  824.     if (isdigit((unsigned)*s))
  825.       return (atoi(s));
  826.   return (0);
  827. }
  828.  
  829.  
  830. static void elf32be_symbols(struct GlobalVars *gv,uint8 *elf,
  831.                             struct ObjectUnit *ou,struct Elf32_Shdr *shdr)
  832. /* convert ELF symbol definitions into internal format */
  833. {
  834.   struct LinkFile *lf = ou->lnkfile;
  835.   uint8 *data = elf + read32be(shdr->sh_offset);
  836.   unsigned long entsize = read32be(shdr->sh_entsize);
  837.   int nsyms = (int)(read32be(shdr->sh_size) / (uint32)entsize);
  838.   char *strtab = elf32be_strtab(lf,(struct Elf32_Ehdr *)elf,
  839.                                 read32be(shdr->sh_link));
  840.   struct Section *sec,*firstsec;
  841.   struct Elf32_Sym *elfsym;
  842.  
  843.   if ((data < lf->data) || 
  844.       (data + read32be(shdr->sh_size) > lf->data + lf->length))
  845.     error(51,lf->pathname,"symbol",lf->objname);  /* illegal offset */
  846.  
  847.   if (listempty(&ou->sections))  /* not a single section? */
  848.     firstsec = elf32be_bssdefault(ou);
  849.   else
  850.     firstsec = (struct Section *)ou->sections.first;
  851.  
  852.   /* read ELF xdef symbols and convert to internal format */
  853.   while (--nsyms > 0) {
  854.     int shndx;
  855.     char *symname;
  856.     uint8 type,objinfo,objbind;
  857.  
  858.     elfsym = (struct Elf32_Sym *)(data += entsize);
  859.     symname = strtab + read32be(elfsym->st_name);
  860.     switch (shndx = (int)read16be(elfsym->st_shndx)) {
  861.       case SHN_UNDEF:
  862.         sec = NULL;  /* ignore xrefs for now */
  863.         break;
  864.       /* assign a section for ABS and COMMON symbols, to prevent */
  865.       /* accidental NULL-pointer references */
  866.       case SHN_ABS:
  867.         sec = firstsec;
  868.         type = SYM_ABS;
  869.         break;
  870.       case SHN_COMMON:
  871.         sec = firstsec;
  872.         type = SYM_COMMON;
  873.         break;
  874.       /* reloc symbols have a definite section to which they belong */
  875.       default:
  876.         if (!(sec = find_sect_id(ou,shndx))) {
  877.           /* a section with this index doesn't exist! */
  878.           if (ELF32_ST_TYPE(*elfsym->st_info) != STT_SECTION)
  879.             error(53,lf->pathname,symname,lf->objname,shndx);
  880.         }
  881.         type = SYM_RELOC;
  882.         break;
  883.     }
  884.  
  885.     if ((objinfo = ELF32_ST_TYPE(*elfsym->st_info)) == STT_SECTION)
  886.       sec = NULL;  /* ignore section defines - will be reproduced */
  887.  
  888.     if (sec) {
  889.       struct Symbol *sym;
  890.  
  891.       if (objinfo > STT_FILE) {
  892.         /* illegal symbol type */
  893.         error(54,lf->pathname,(int)objinfo,symname,lf->objname);
  894.         objinfo = STT_NOTYPE;
  895.       }
  896.       switch (ELF32_ST_BIND(*elfsym->st_info)) {
  897.         case STB_LOCAL:
  898.           objbind = SYMB_LOCAL;
  899.           break;
  900.         case STB_GLOBAL:
  901.           objbind = SYMB_GLOBAL;
  902.           break;
  903.         case STB_WEAK:
  904.           objbind = SYMB_WEAK;
  905.           break;
  906.         default:  /* illegal binding type */
  907.           error(55,lf->pathname,symname,ELF32_ST_BIND(*elfsym->st_info),
  908.                 lf->objname);
  909.           objbind = SYMB_LOCAL;
  910.           break;
  911.       }
  912.  
  913.       /* add a new symbol definition */
  914.       if (objbind == SYMB_LOCAL) {
  915.         /* always define local symbols - multiple defintions allowed */
  916.         addlocsymbol(gv,sec,symname,read32be(elfsym->st_value),type,0,
  917.                      objinfo,read32be(elfsym->st_size));
  918.       }
  919.       else {
  920.         if (sym = addsymbol(gv,sec,symname,read32be(elfsym->st_value),type,
  921.                             0,objinfo,objbind,read32be(elfsym->st_size))) {
  922.           /* symbol is multiply defined! */
  923.           struct LinkFile *lf2 = sym->relsect->obj->lnkfile;
  924.           char buf[256];  /* @@@ dangerous... */
  925.  
  926.           if (lf2->type == ID_LIBARCH)
  927.             sprintf(buf,"%s (%s)",lf2->filename,lf2->objname);
  928.           else
  929.             strcpy(buf,lf2->objname);
  930.           error(56,lf->pathname,symname,lf->objname,buf);
  931.         }
  932.       }
  933.       if (objbind == SYMB_GLOBAL && !gv->dest_object) {
  934.       /* symbol describes an automatic vbcc con-/destructor function ? */
  935.         if (!strncmp(vbcc_INIT,symname,sizeof(vbcc_INIT)-1))
  936.           new_priptr(sec->obj,xtors_objname,elf32_symnames[CTORS],
  937.                      get_xtors_pri(symname+(sizeof(vbcc_INIT)-1)),symname,0);
  938.         else if (!strncmp(vbcc_EXIT,symname,sizeof(vbcc_EXIT)-1))
  939.           new_priptr(sec->obj,xtors_objname,elf32_symnames[DTORS],
  940.                      get_xtors_pri(symname+(sizeof(vbcc_EXIT)-1)),symname,0);
  941.       }
  942.     }
  943.   }
  944. }
  945.  
  946.  
  947. static void elf32be_reloc(struct GlobalVars *gv,struct Elf32_Ehdr *elf,
  948.                           struct Section *s,uint32 symndx,
  949.                           struct Elf32_Rela *rel,bool rela,uint8 rtype)
  950. /* Insert relocations, which are relative to a defined symbol, into */
  951. /* the section's reloc-list. If the symbol is undefined, create an */
  952. /* external reference on it, with the supplied relocation type. */
  953. {
  954.   struct LinkFile *lf = s->obj->lnkfile;
  955.   struct Elf32_Shdr *symhdr = elf32be_shdr(lf,elf,symndx);
  956.   struct Elf32_Sym *sym = elf32be_symtab(lf,elf,symndx) +
  957.                           ELF32_R_SYM(read32be(rel->r_info));
  958.   uint32 offs = read32be(rel->r_offset);
  959.   uint32 shndx = (uint32)read16be(sym->st_shndx);
  960.   int32 a;
  961.  
  962.   /* if addend isn't defined in Reloc, read it from the section data */
  963.   if (rela)
  964.     a = (int32)read32be(rel->r_addend);
  965.   else
  966.     a = readsection(gv,s->data+offs,rtype);
  967.  
  968.   if (shndx == SHN_UNDEF) {
  969.     /* undefined symbol - create external reference */
  970.     char *xrefname = elf32be_strtab(lf,elf,read32be(symhdr->sh_link)) +
  971.                                     read32be(sym->st_name);
  972.  
  973.     addxref(gv,s,xrefname,offs,rtype,relocsize(rtype),a);
  974.   }
  975.  
  976.   else if (ELF32_ST_TYPE(*sym->st_info) == STT_SECTION) {
  977.     /* a normal relocation, with an offset relative to a section base */
  978.  
  979.     addreloc(s,find_sect_id(s->obj,shndx),0,offs,rtype,a);
  980.   }
  981.  
  982.   else if (ELF32_ST_TYPE(*sym->st_info)<STT_SECTION && shndx<SHN_ABS) {
  983.     /* relocations, which are relative to a known symbol */
  984.  
  985.     addreloc(s,find_sect_id(s->obj,shndx),0,offs,rtype,
  986.              (int32)read32be(sym->st_value) + a);
  987.   }
  988.  
  989.   else
  990.     ierror("elf32be_reloc(): %s (%s): Only relocations which are relative "
  991.            "to a section, function or object are supported",
  992.            lf->pathname,lf->objname);
  993. }
  994.  
  995.  
  996. static struct Section *elf32be_bssdefault(struct ObjectUnit *ou)
  997. /* Create a default BSS section for ELF32 BigEndian */
  998. {
  999.   static char *bssname = ".bss";
  1000.   struct Section *s = create_section(ou,bssname,NULL,0);
  1001.  
  1002.   s->flags |= SF_UNINITIALIZED;
  1003.   s->type = ST_UDATA;
  1004.   s->protection = SP_READ | SP_WRITE;
  1005.   s->alignment = 4;  /* @@@ */
  1006.   return (s);
  1007. }
  1008.  
  1009.  
  1010. static int elf32_targetlink(struct GlobalVars *gv,struct LinkedSection *ls,
  1011.                             struct Section *s)
  1012. /* returns 1, if target requires the combination of the two sections, */
  1013. /* returns -1, if target don't want to combine them, */
  1014. /* returns 0, if target doesn't care - standard linking rules are used. */
  1015. {
  1016.   if (!gv->dest_object) {
  1017.     if ((!strncmp(ls->name,sdata,6) && !strncmp(s->name,sbss,5)
  1018.          && *(ls->name+6) == *(s->name+5)) ||
  1019.         (!strncmp(ls->name,sbss,5) && !strncmp(s->name,sdata,6)
  1020.          && *(ls->name+5) == *(s->name+6)))
  1021.       /* .sdata/.sbss, .sdata2/.sbss2, etc. are always combined */
  1022.       return (1);
  1023.   }
  1024.  
  1025.   return (0);
  1026. }
  1027.  
  1028.  
  1029. static struct Symbol *elf32_lnksym(struct GlobalVars *gv,
  1030.                                    struct Section *sec,
  1031.                                    struct XReference *xref,
  1032.                                    struct FFFuncs *tf)
  1033. /* Check for common ELF32 linker symbols. */
  1034. {
  1035.   struct Symbol *sym;
  1036.   int i;
  1037.  
  1038.   if (sym = findlnksymbol(tf,xref->name))
  1039.     return (sym);
  1040.  
  1041.   if (!gv->dest_object) {
  1042.     for (i=0; i<ELF32_LNKSYMS; i++) {
  1043.       if (!strcmp(elf32_symnames[i],xref->name)) {
  1044.         sym = addlnksymbol(tf,NULL,elf32_symnames[i],0,SYM_ABS,
  1045.                            SYMF_LNKSYM,SYMI_OBJECT,SYMB_GLOBAL,0);
  1046.         sym->extra = i;             /* for easy ident. in elf32_setlnksym */
  1047.         switch (i) {
  1048.           case SDABASE:
  1049.           case SDA2BASE:
  1050.             sym->type = SYM_RELOC;
  1051.             sym->value = (uint32)tf->baseoff;
  1052.             break;
  1053.         }
  1054.         return (sym);  /* new linker symbol created */
  1055.       }
  1056.     }
  1057.   }
  1058.   return (NULL);
  1059. }
  1060.  
  1061.  
  1062. static void elf32_setlnksym(struct GlobalVars *gv,struct Symbol *xdef,
  1063.                             struct XReference *xref,struct FFFuncs *tf)
  1064. /* Initialize common ELF32 linker symbol structure during resolve_xref() */
  1065. {
  1066.   if (xdef->flags & SYMF_LNKSYM) {
  1067.     struct LinkedSection *ls;
  1068.  
  1069.     switch (xdef->extra) {
  1070.       case SDABASE:
  1071.         if (!(ls = find_lnksec(gv,sdata,ST_DATA,0,0)))
  1072.           if (!(ls = find_lnksec(gv,sbss,ST_UDATA,0,0)))
  1073.             ls = smalldata_section(gv);
  1074.         xdef->relsect = (struct Section *)ls->sections.first;
  1075.         break;
  1076.       case SDA2BASE:
  1077.         if (!(ls = find_lnksec(gv,sdata2,ST_DATA,0,0)))
  1078.           if (!(ls = find_lnksec(gv,sbss2,ST_UDATA,0,0)))
  1079.             ls = smalldata_section(gv);
  1080.         xdef->relsect = (struct Section *)ls->sections.first;
  1081.         break;
  1082.       case CTORS:
  1083.         if (ls = find_lnksec(gv,elf32_symnames[CTORS],0,0,0)) {
  1084.           xdef->type = SYM_RELOC;
  1085.           xdef->relsect = (struct Section *)ls->sections.first;
  1086.         }
  1087.         break;
  1088.       case DTORS:
  1089.         if (ls = find_lnksec(gv,elf32_symnames[DTORS],0,0,0)) {
  1090.           xdef->type = SYM_RELOC;
  1091.           xdef->relsect = (struct Section *)ls->sections.first;
  1092.         }
  1093.         break;
  1094.     }
  1095.     xdef->flags &= ~SYMF_LNKSYM;  /* do not init again */
  1096.   }
  1097. }
  1098.  
  1099.  
  1100.  
  1101. /*****************************************************************/
  1102. /*                          Write ELF                            */
  1103. /*****************************************************************/
  1104.  
  1105.  
  1106. #ifdef ELF32_PPC_BE
  1107.  
  1108. static void ppc32be_writeshared(struct GlobalVars *gv,FILE *f)
  1109. /* creates a target-elfppc32be shared object (which is pos. independant) */
  1110. {
  1111.   ierror("ppc32be_writeshared(): Shared object generation has not "
  1112.          "yet been implemented");
  1113. }
  1114.  
  1115.  
  1116. static void ppc32be_writeobject(struct GlobalVars *gv,FILE *f)
  1117. /* creates a target-elfppc32be relocatable object file */
  1118. {
  1119.   uint32 sh_off,shstrndx,stabndx;
  1120.  
  1121.   elf32_initlists();
  1122.   elf32be_addsym(&symlist,nullstr,0,0,0,0,SHN_UNDEF);
  1123.   if (gv->discard_local < DISLOC_ALL)
  1124.     elf32be_stdsymtab(gv,STB_LOCAL,STT_FILE);
  1125.  
  1126.   elf32be_makeshdrs(gv);
  1127.   if (gv->discard_local < DISLOC_ALL)
  1128.     elf32be_stdsymtab(gv,STB_LOCAL,0);
  1129.   symlist.global_index = symlist.nextindex;
  1130.   if (gv->strip_symbols < STRIP_ALL) { /* although not recomm. for objects */
  1131.     elf32be_stdsymtab(gv,STB_WEAK,0);
  1132.     elf32be_stdsymtab(gv,STB_GLOBAL,0);
  1133.   }
  1134.   elf32be_addrelocs(gv,ppc32be_getrel);
  1135.  
  1136.   shstrndx = shdrindex;
  1137.   elf32be_makeshstrtab();
  1138.   sh_off = elfoffset;
  1139.   stabndx = shdrindex;
  1140.   elfoffset += (shdrindex+2) * sizeof(struct Elf32_Shdr);
  1141.   elf32be_makesymtab(shdrindex+1);
  1142.   elf32be_makestrtab();
  1143.  
  1144.   elf32be_header(f,ET_REL,EM_PPC,0,0,sh_off,0,0,shdrindex,shstrndx);
  1145.   elf32_writesections(gv,f);
  1146.   elf32_writestrtab(f,&shstrlist);
  1147.   fwrite_align(f,2,ftell(f));
  1148.   elf32be_writeshdrs(f,elfoffset,stabndx);
  1149.   elf32_writesymtab(f,&symlist);
  1150.   elf32_writestrtab(f,&stringlist);
  1151.   fwrite_align(f,2,ftell(f));
  1152.   elf32_writerelocs(gv,f);
  1153. }
  1154.  
  1155.  
  1156. static void ppc32be_writeexec(struct GlobalVars *gv,FILE *f)
  1157. /* creates a target-elfppc32be executable file (with absolute addresses) */
  1158. {
  1159.   ierror("ppc32be_writeexec(): Executable file generation has not "
  1160.          "yet been implemented");
  1161. }
  1162.  
  1163.  
  1164. static uint8 ppc32be_getrel(uint8 rtype,char *sname,uint32 offs)
  1165. {
  1166.   switch (rtype) {
  1167.     case R_NONE:
  1168.       break;
  1169.     case R_ADDR32:
  1170.       return (R_PPC_ADDR32);
  1171.     case R_ADDR26:
  1172.       return (R_PPC_ADDR24);
  1173.     case R_ADDR16:
  1174.       return (R_PPC_ADDR16);
  1175.     case R_ADDR16_LO:
  1176.       return (R_PPC_ADDR16_LO);
  1177.     case R_ADDR16_HI:
  1178.       return (R_PPC_ADDR16_HI);
  1179.     case R_ADDR16_HA:
  1180.       return (R_PPC_ADDR16_HA);
  1181.     case R_ADDR14:
  1182.       return (R_PPC_ADDR14);
  1183.     case R_ADDR14_BRTAKEN:
  1184.       return (R_PPC_ADDR14_BRTAKEN);
  1185.     case R_ADDR14_BRNTAKEN:
  1186.       return (R_PPC_ADDR14_BRNTAKEN);
  1187.     case R_REL26:
  1188.       return (R_PPC_REL24);
  1189.     case R_REL14:
  1190.       return (R_PPC_REL14);
  1191.     case R_REL14_BRTAKEN:
  1192.       return (R_PPC_REL14_BRTAKEN);
  1193.     case R_REL14_BRNTAKEN:
  1194.       return (R_PPC_REL14_BRNTAKEN);
  1195.     case R_BASEREL16:
  1196.       return (R_PPC_SDAREL16);
  1197.     default:
  1198.       /* unsupported relocation type */
  1199.       error(32,fff_elf32ppcbe.tname,reloc_name[rtype],sname,offs);
  1200.       break;
  1201.   }
  1202.   return (R_NONE);
  1203. }
  1204.  
  1205. #endif /* ELF32_PPC_BE */
  1206.  
  1207.  
  1208. #ifdef ELF32_POWERUP
  1209.  
  1210. static void powerup_writeshared(struct GlobalVars *gv,FILE *f)
  1211. /* creates a target-elf32powerup shared object (which is pos. independant) */
  1212. {
  1213.   ierror("powerup_writeshared(): Shared object generation has not "
  1214.          "yet been implemented");
  1215. }
  1216.  
  1217.  
  1218. static void powerup_writeobject(struct GlobalVars *gv,FILE *f)
  1219. /* creates a target-elf32powerup relocatable object file */
  1220. {
  1221.   uint32 sh_off,shstrndx,stabndx;
  1222.  
  1223.   elf32_initlists();
  1224.   elf32be_addsym(&symlist,nullstr,0,0,0,0,SHN_UNDEF);
  1225.   if (gv->discard_local < DISLOC_ALL)
  1226.     elf32be_stdsymtab(gv,STB_LOCAL,STT_FILE);
  1227.  
  1228.   elf32be_makeshdrs(gv);
  1229.   if (gv->discard_local < DISLOC_ALL)
  1230.     elf32be_stdsymtab(gv,STB_LOCAL,0);
  1231.   symlist.global_index = symlist.nextindex;
  1232. #if 0 /*@@@ strip all for object?*/
  1233.   if (gv->strip_symbols < STRIP_ALL) {
  1234.     elf32be_stdsymtab(gv,STB_WEAK,0);
  1235.     elf32be_stdsymtab(gv,STB_GLOBAL,0);
  1236.   }
  1237. #endif
  1238.   elf32be_addrelocs(gv,powerup_getrel);
  1239.  
  1240.   shstrndx = shdrindex;
  1241.   elf32be_makeshstrtab();
  1242.   sh_off = elfoffset;
  1243.   stabndx = shdrindex;
  1244.   elfoffset += (shdrindex+2) * sizeof(struct Elf32_Shdr);
  1245.   elf32be_makesymtab(shdrindex+1);
  1246.   elf32be_makestrtab();
  1247.  
  1248.   elf32be_header(f,ET_REL,EM_PPC,0,0,sh_off,0,0,shdrindex,shstrndx);
  1249.   elf32_writesections(gv,f);
  1250.   elf32_writestrtab(f,&shstrlist);
  1251.   fwrite_align(f,2,ftell(f));
  1252.   elf32be_writeshdrs(f,elfoffset,stabndx);
  1253.   elf32_writesymtab(f,&symlist);
  1254.   elf32_writestrtab(f,&stringlist);
  1255.   fwrite_align(f,2,ftell(f));
  1256.   elf32_writerelocs(gv,f);
  1257. }
  1258.  
  1259.  
  1260. static void powerup_writeexec(struct GlobalVars *gv,FILE *f)
  1261. /* creates a target-elf32powerup executable file, which in reality */
  1262. /* is a relocatable object too, but all symbol references have */
  1263. /* been resolved */
  1264. {
  1265.   uint32 sh_off,shstrndx,stabndx;
  1266.   struct LinkedSection *ls;
  1267.  
  1268.   /* rename .ctors into .ctor_ and .dtors into .dtor_, otherwise */
  1269.   /* the PowerUp ELF loader will rearrange the pointers */
  1270.   if (ls = find_lnksec(gv,elf32_symnames[CTORS],0,0,0))
  1271.     ls->name[5] = '_';
  1272.   if (ls = find_lnksec(gv,elf32_symnames[DTORS],0,0,0))
  1273.     ls->name[5] = '_';
  1274.  
  1275.   elf32_initlists();
  1276.   elf32be_addsym(&symlist,nullstr,0,0,0,0,SHN_UNDEF);
  1277.   if (gv->discard_local < DISLOC_ALL)
  1278.     elf32be_stdsymtab(gv,STB_LOCAL,STT_FILE);
  1279.  
  1280.   elf32be_makeshdrs(gv);
  1281.   if (gv->discard_local < DISLOC_ALL)
  1282.     elf32be_stdsymtab(gv,STB_LOCAL,0);
  1283.   symlist.global_index = symlist.nextindex;
  1284.   if (gv->strip_symbols < STRIP_ALL) {
  1285.     elf32be_stdsymtab(gv,STB_WEAK,0);
  1286.     elf32be_stdsymtab(gv,STB_GLOBAL,0);
  1287.   }
  1288.   elf32be_addrelocs(gv,powerup_getrel);
  1289.  
  1290.   shstrndx = shdrindex;
  1291.   elf32be_makeshstrtab();
  1292.   sh_off = elfoffset;
  1293.   stabndx = shdrindex;
  1294.   elfoffset += (shdrindex+2) * sizeof(struct Elf32_Shdr);
  1295.   elf32be_makesymtab(shdrindex+1);
  1296.   elf32be_makestrtab();
  1297.  
  1298.   elf32be_header(f,ET_REL,EM_PPC,0,0,sh_off,0,0,shdrindex,shstrndx);
  1299.   elf32_writesections(gv,f);
  1300.   elf32_writestrtab(f,&shstrlist);
  1301.   fwrite_align(f,2,ftell(f));
  1302.   elf32be_writeshdrs(f,elfoffset,stabndx);
  1303.   elf32_writesymtab(f,&symlist);
  1304.   elf32_writestrtab(f,&stringlist);
  1305.   fwrite_align(f,2,ftell(f));
  1306.   elf32_writerelocs(gv,f);
  1307. }
  1308.  
  1309.  
  1310. static uint8 powerup_getrel(uint8 rtype,char *sname,uint32 offs)
  1311. {
  1312.   switch (rtype) {
  1313.     case R_NONE:
  1314.       break;
  1315.     case R_ADDR32:
  1316.       return (R_PPC_ADDR32);
  1317.     case R_ADDR26:
  1318.       return (R_PPC_ADDR24);
  1319.     case R_ADDR16:
  1320.       return (R_PPC_ADDR16);
  1321.     case R_ADDR16_LO:
  1322.       return (R_PPC_ADDR16_LO);
  1323.     case R_ADDR16_HI:
  1324.       return (R_PPC_ADDR16_HI);
  1325.     case R_ADDR16_HA:
  1326.       return (R_PPC_ADDR16_HA);
  1327.     case R_ADDR14:
  1328.       return (R_PPC_ADDR14);
  1329.     case R_ADDR14_BRTAKEN:
  1330.       return (R_PPC_ADDR14_BRTAKEN);
  1331.     case R_ADDR14_BRNTAKEN:
  1332.       return (R_PPC_ADDR14_BRNTAKEN);
  1333.     case R_REL26:
  1334.       return (R_PPC_REL24);
  1335.     case R_REL14:
  1336.       return (R_PPC_REL14);
  1337.     case R_REL14_BRTAKEN:
  1338.       return (R_PPC_REL14_BRTAKEN);
  1339.     case R_REL14_BRNTAKEN:
  1340.       return (R_PPC_REL14_BRNTAKEN);
  1341.     case R_BASEREL16:
  1342.       return (R_PPC_SDAREL16);
  1343.     default:
  1344.       /* unsupported relocation type */
  1345.       error(32,fff_elf32powerup.tname,reloc_name[rtype],sname,offs);
  1346.       break;
  1347.   }
  1348.   return (R_NONE);
  1349. }
  1350. #endif /* ELF32_POWERUP */
  1351.  
  1352.  
  1353. static void elf32be_header(FILE *f,uint16 type,uint16 mach,uint32 entry,
  1354.                            uint32 phoff,uint32 shoff,uint32 flags,
  1355.                            uint16 phnum,uint16 shnum,uint16 shstrndx)
  1356. /* write ELF header for 32-bit big endian */
  1357. {
  1358.   struct Elf32_Ehdr eh;
  1359.  
  1360.   memset(&eh,0,sizeof(struct Elf32_Ehdr));
  1361.   strncpy((char *)eh.e_ident,ELFid,4);
  1362.   eh.e_ident[EI_CLASS] = ELFCLASS32;
  1363.   eh.e_ident[EI_DATA] = ELFDATA2MSB;
  1364.   eh.e_ident[EI_VERSION] = ELF_VER;
  1365.   write16be(eh.e_type,type);
  1366.   write16be(eh.e_machine,mach);
  1367.   write32be(eh.e_version,ELF_VER);
  1368.   write32be(eh.e_entry,entry);
  1369.   write32be(eh.e_phoff,phoff);
  1370.   write32be(eh.e_shoff,shoff);
  1371.   write32be(eh.e_flags,flags);
  1372.   write16be(eh.e_ehsize,sizeof(struct Elf32_Ehdr));
  1373.   write16be(eh.e_phentsize,phnum ? sizeof(struct Elf32_Phdr):0);
  1374.   write16be(eh.e_phnum,phnum);
  1375.   write16be(eh.e_shentsize,shnum ? sizeof(struct Elf32_Shdr):0);
  1376.   write16be(eh.e_shnum,shnum);
  1377.   write16be(eh.e_shstrndx,shstrndx);
  1378.   fwritex(f,&eh,sizeof(struct Elf32_Ehdr));
  1379. }
  1380.  
  1381.  
  1382. static void elf32be_writeshdrs(FILE *f,uint32 reloffset,uint32 stabndx)
  1383. /* write all section headers */
  1384. {
  1385.   struct ShdrNode *shn;
  1386.   uint32 type;
  1387.  
  1388.   while (shn = (struct ShdrNode *)remhead(&shdrlist)) {
  1389.     type = read32be(shn->s.sh_type);
  1390.     if (type == SHT_RELA || type == SHT_REL) {
  1391.       /* patch correct sh_offset and sh_link for reloc header */
  1392.       write32be(shn->s.sh_offset,read32be(shn->s.sh_offset)+reloffset);
  1393.       write32be(shn->s.sh_link,stabndx);
  1394.     }
  1395.     fwritex(f,&shn->s,sizeof(struct Elf32_Shdr));
  1396.   }
  1397. }
  1398.  
  1399.  
  1400. static void elf32be_stdsymtab(struct GlobalVars *gv,uint8 bind,uint8 type)
  1401. {
  1402.   elf32be_addsymlist(gv,&symlist,bind,type);
  1403. }
  1404.  
  1405.  
  1406. static void elf32be_addsymlist(struct GlobalVars *gv,struct SymTabList *sl,
  1407.                                uint8 bind,uint8 type)
  1408. /* add all symbols with specified bind and type to the ELF symbol list */
  1409. {
  1410.   struct LinkedSection *ls = (struct LinkedSection *)gv->lnksec.first;
  1411.   struct LinkedSection *nextls;
  1412.   struct Symbol *nextsym,*sym;
  1413.  
  1414.   while (nextls = (struct LinkedSection *)ls->n.next) {
  1415.     sym = (struct Symbol *)ls->symbols.first;
  1416.  
  1417.     while (nextsym = (struct Symbol *)sym->n.next) {
  1418.       uint8 symtype = elf32_getinfo(sym);
  1419.       uint8 symbind = elf32_getbind(sym);
  1420.  
  1421.       if (symbind == bind && (!type || (symtype == type))) {
  1422.         remnode(&sym->n);
  1423.         elf32be_addsym(sl,sym->name,sym->value,sym->size,
  1424.                        symbind,symtype,elf32_getshndx(sym,symtype));
  1425. #ifndef FASTALLOC
  1426.         free(sym);
  1427. #endif
  1428.       }
  1429.       sym = nextsym;
  1430.     }
  1431.     ls = nextls;
  1432.   }
  1433. }
  1434.  
  1435.  
  1436. static void elf32be_makeshdrs(struct GlobalVars *gv)
  1437. /* generate all ELF section headers */
  1438. {
  1439.   struct LinkedSection *ls = (struct LinkedSection *)gv->lnksec.first;
  1440.   struct LinkedSection *nextls;
  1441.   struct ShdrNode *shn;
  1442.   struct SymbolNode *sym;
  1443.   uint32 f;
  1444.   bool bss;
  1445.  
  1446.   /* offset, to find section-symbols by section header index */
  1447.   secsyms = (int)symlist.nextindex - (int)shdrindex;
  1448.  
  1449.   while (nextls = (struct LinkedSection *)ls->n.next) {
  1450.     ls->index = (int)shdrindex;
  1451.     bss = ls->type==ST_UDATA || (ls->flags&SF_UNINITIALIZED);
  1452.     f = (ls->flags & SF_DISCARD) ? 0 : SHF_ALLOC;
  1453.     if (ls->protection & SP_WRITE)
  1454.       f |= SHF_WRITE;
  1455.     if (ls->protection & SP_EXEC)
  1456.       f |= SHF_EXECINSTR;
  1457.     elf32be_addshdr(elf32_addshdrstr(ls->name),bss?SHT_NOBITS:SHT_PROGBITS,
  1458.                     f,0,elfoffset,ls->size,0,0,1<<(uint32)ls->alignment,0);
  1459.     if (!bss)
  1460.       elfoffset += ls->size;
  1461.  
  1462.     /* add section symbol (without name) */
  1463.     elf32be_addsym(&symlist,nullstr,0,0,STB_LOCAL,STT_SECTION,
  1464.                    (uint16)ls->index);
  1465.     ls = nextls;  /* next section */
  1466.   }
  1467. }
  1468.  
  1469.  
  1470. static void elf32be_addrelocs(struct GlobalVars *gv,
  1471.                               uint8 (*getrel)(uint8,char *,uint32))
  1472. /* creates relocations for all sections */
  1473. {
  1474.   struct LinkedSection *ls = (struct LinkedSection *)gv->lnksec.first;
  1475.   struct LinkedSection *nextls;
  1476.   struct Reloc *rel,*nextrel;
  1477.   struct XReference *xref,*nextxref;
  1478.   uint32 symidx,sroffs=0,roffs=0;
  1479.  
  1480.   while (nextls = (struct LinkedSection *)ls->n.next) {
  1481.     sroffs = roffs;
  1482.  
  1483.     /* relocations */
  1484.     rel = (struct Reloc *)ls->relocs.first;
  1485.     while (nextrel = (struct Reloc *)rel->n.next) {
  1486.       elf32be_addrela((uint32)rel->offset,rel->addend,
  1487.                       (uint32)(rel->relocsect.lnk->index + secsyms),
  1488.                       getrel(rel->type,ls->name,(uint32)rel->offset));
  1489.       roffs += gv->short_rel ?
  1490.                sizeof(struct Elf32_Rel) : sizeof(struct Elf32_Rela);
  1491.       rel = nextrel;
  1492.     }
  1493.  
  1494.     /* external references */
  1495.     xref = (struct XReference *)ls->xrefs.first;
  1496.     while (nextxref = (struct XReference *)xref->n.next) {
  1497.       /* undefined symbol */
  1498.       if (!(symidx = elf32be_findsym(&symlist,xref->name,SHN_UNDEF)))
  1499.         symidx = elf32be_addsym(&symlist,xref->name,0,0,STB_GLOBAL,
  1500.                                 STT_NOTYPE,SHN_UNDEF);
  1501.       /* symbol's relocation */
  1502.       elf32be_addrela((uint32)xref->offset,xref->addend,symidx,
  1503.                       getrel(xref->type,ls->name,(uint32)xref->offset));
  1504.       roffs += gv->short_rel ?
  1505.                sizeof(struct Elf32_Rel) : sizeof(struct Elf32_Rela);
  1506.       xref = nextxref;
  1507.     }
  1508.  
  1509.     if (roffs != sroffs) {
  1510.       /* create ".rel(a).name" header */
  1511.       char *relname = (char *)alloc(strlen(ls->name)+6);
  1512.  
  1513.       sprintf(relname,".%s%s",gv->short_rel ? "rel":"rela",ls->name);
  1514.       elf32be_addshdr(elf32_addshdrstr(relname),
  1515.                       gv->short_rel ? SHT_REL:SHT_RELA,
  1516.                       0,0,sroffs,roffs-sroffs,0,(uint32)ls->index,4,
  1517.                       gv->short_rel ? sizeof(struct Elf32_Rel) : 
  1518.                                       sizeof(struct Elf32_Rela));
  1519.       /* sroffs is relative and will be corrected later */
  1520.       /* sh_link will be initialized, when .symtab exists */
  1521.     }
  1522.     ls = nextls;  /* next section */
  1523.   }
  1524. }
  1525.  
  1526.  
  1527. static void elf32be_makeshstrtab()
  1528. /* creates .shstrtab */
  1529. {
  1530.   elf32be_addshdr(shstrtabidx,SHT_STRTAB,0,0,elfoffset,
  1531.                   shstrlist.nextindex,0,0,1,0);
  1532.   elfoffset += shstrlist.nextindex;
  1533.   elfoffset += align(elfoffset,2);
  1534. }
  1535.  
  1536.  
  1537. static void elf32be_makestrtab()
  1538. /* creates .strtab */
  1539. {
  1540.   elf32be_addshdr(strtabidx,SHT_STRTAB,0,0,elfoffset,
  1541.                   stringlist.nextindex,0,0,1,0);
  1542.   elfoffset += stringlist.nextindex;
  1543.   elfoffset += align(elfoffset,2);
  1544. }
  1545.  
  1546.  
  1547. static void elf32be_makesymtab(uint32 strtabindex)
  1548. /* creates .symtab */
  1549. {
  1550.   elf32be_addshdr(symtabidx,SHT_SYMTAB,0,0,elfoffset,
  1551.                   symlist.nextindex * sizeof(struct Elf32_Sym),
  1552.                   strtabindex,symlist.global_index,4,
  1553.                   sizeof(struct Elf32_Sym));
  1554.   elfoffset += symlist.nextindex * sizeof(struct Elf32_Sym);
  1555. }
  1556.  
  1557.  
  1558. static struct ShdrNode *elf32be_addshdr(uint32 name,uint32 type,uint32 flags,
  1559.                                         uint32 addr,uint32 offset,
  1560.                                         uint32 size,uint32 link,uint32 info,
  1561.                                         uint32 align,uint32 entsize)
  1562. {
  1563.   struct ShdrNode *shn = elf32_newshdr();
  1564.  
  1565.   write32be(shn->s.sh_name,name);
  1566.   write32be(shn->s.sh_type,type);
  1567.   write32be(shn->s.sh_flags,flags);
  1568.   write32be(shn->s.sh_addr,addr);
  1569.   write32be(shn->s.sh_offset,offset);
  1570.   write32be(shn->s.sh_size,size);
  1571.   write32be(shn->s.sh_link,link);
  1572.   write32be(shn->s.sh_info,info);
  1573.   write32be(shn->s.sh_addralign,align);
  1574.   write32be(shn->s.sh_entsize,entsize);
  1575.   return (shn);
  1576. }
  1577.  
  1578.  
  1579. static uint32 elf32be_addsym(struct SymTabList *sl,char *name,uint32 value,
  1580.                              uint32 size,uint8 bind,uint8 type,uint16 shndx)
  1581. /* add a new ELF symbol, return its symbol table index */
  1582. {
  1583.   struct SymbolNode **chain = &sl->hashtab[elf_hash(name) % SYMHTABSIZE];
  1584.   struct SymbolNode *sym;
  1585.  
  1586.   while (sym = *chain)
  1587.     chain = &sym->hashchain;
  1588.   /* new symbol table entry */
  1589.   *chain = sym = alloczero(sizeof(struct SymbolNode));
  1590.   sym->name = name;
  1591.   sym->index = sl->nextindex++;
  1592.   addtail(&sl->l,&sym->n);
  1593.   write32be(sym->s.st_name,elf32_addstr(name));
  1594.   write32be(sym->s.st_value,value);
  1595.   write32be(sym->s.st_size,size);
  1596.   *sym->s.st_info = ELF32_ST_INFO(bind,type);
  1597.   write16be(sym->s.st_shndx,shndx);
  1598.   return (sym->index);
  1599. }
  1600.  
  1601.  
  1602. static uint32 elf32be_findsym(struct SymTabList *sl,char *name,uint16 shndx)
  1603. /* find an ELF symbol by its name and shndx */
  1604. /* return its symbol table index, index=0 means 'not found' */
  1605. {
  1606.   struct SymbolNode **chain = &sl->hashtab[elf_hash(name) % SYMHTABSIZE];
  1607.   struct SymbolNode *sym;
  1608.  
  1609.   while (sym = *chain) {
  1610.     if (!strcmp(name,sym->name))
  1611.       if (read16be(sym->s.st_shndx) == shndx)
  1612.         return (sym->index);
  1613.     chain = &sym->hashchain;
  1614.   }
  1615.   return (0);
  1616. }
  1617.  
  1618.  
  1619. static void elf32be_addrela(uint32 offs,int32 addend,uint32 sym,uint8 type)
  1620. {
  1621.   struct RelaNode *rn = alloc(sizeof(struct RelaNode));
  1622.  
  1623.   write32be(rn->r.r_offset,offs);
  1624.   write32be(rn->r.r_addend,addend);
  1625.   write32be(rn->r.r_info,ELF32_R_INFO(sym,(uint32)type));
  1626.   addtail(&relalist,&rn->n);
  1627. }
  1628.  
  1629.  
  1630. static void elf32_initlists()
  1631. /* initialize section header, program header, relocation, symbol, */
  1632. /* string and section header string lists */
  1633. {
  1634.   static struct StrTabNode *str_hashtab[STRHTABSIZE];
  1635.   static struct StrTabNode *shstr_hashtab[SHSTRHTABSIZE];
  1636.   static struct SymbolNode *sym_hashtab[SYMHTABSIZE];
  1637.  
  1638.   elfoffset = sizeof(struct Elf32_Ehdr);
  1639.   initlist(&shdrlist);
  1640.   initlist(&phdrlist);
  1641.   initlist(&relalist);
  1642.   shdrindex = 0;
  1643.  
  1644.   initlist(&symlist.l);
  1645.   symlist.hashtab = sym_hashtab;
  1646.   memset(sym_hashtab,0,SYMHTABSIZE*sizeof(struct SymbolNode *));
  1647.   symlist.nextindex = symlist.global_index = 0;
  1648.  
  1649.   initlist(&shstrlist.l);
  1650.   initlist(&stringlist.l);
  1651.   shstrlist.hashtab = shstr_hashtab;
  1652.   stringlist.hashtab = str_hashtab;
  1653.   shstrlist.nextindex = stringlist.nextindex = 0;
  1654.   stringlist.htabsize = STRHTABSIZE;
  1655.   shstrlist.htabsize = SHSTRHTABSIZE;
  1656.   memset(shstr_hashtab,0,SHSTRHTABSIZE*sizeof(struct StrTabNode *));
  1657.   memset(str_hashtab,0,STRHTABSIZE*sizeof(struct StrTabNode *));
  1658.  
  1659.   elf32_addshdrstr(nullstr);  /* first string is always "" */
  1660.   symtabidx = elf32_addshdrstr(".symtab");
  1661.   strtabidx = elf32_addshdrstr(".strtab");
  1662.   shstrtabidx = elf32_addshdrstr(".shstrtab");
  1663.   elf32_addstr(nullstr);
  1664.   elf32_newshdr();          /* first Shdr is always zero */
  1665. }
  1666.  
  1667.  
  1668. static struct ShdrNode *elf32_newshdr()
  1669. {
  1670.   struct ShdrNode *s = alloczero(sizeof(struct ShdrNode));
  1671.  
  1672.   addtail(&shdrlist,&s->n);
  1673.   ++shdrindex;
  1674.   return (s);
  1675. }
  1676.  
  1677.  
  1678. static uint32 elf32_addshdrstr(char *s)
  1679. {
  1680.   return (elf32_addstrlist(&shstrlist,s));
  1681. }
  1682.  
  1683.  
  1684. static uint32 elf32_addstr(char *s)
  1685. {
  1686.   return (elf32_addstrlist(&stringlist,s));
  1687. }
  1688.  
  1689.  
  1690. static uint32 elf32_addstrlist(struct StrTabList *sl,char *s)
  1691. /* add a new string to an ELF string table and return its index */
  1692. {
  1693.   struct StrTabNode **chain = &sl->hashtab[elf_hash(s) % sl->htabsize];
  1694.   struct StrTabNode *sn;
  1695.  
  1696.   /* search string in hash table */
  1697.   while (sn = *chain) {
  1698.     if (!strcmp(s,sn->str))
  1699.       return (sn->index);  /* it's already in, return index */
  1700.     chain = &sn->hashchain;
  1701.   }
  1702.  
  1703.   /* new string table entry */
  1704.   *chain = sn = alloc(sizeof(struct StrTabNode));
  1705.   sn->hashchain = NULL;
  1706.   sn->str = s;
  1707.   sn->index = sl->nextindex;
  1708.   addtail(&sl->l,&sn->n);
  1709.   sl->nextindex += (uint32)strlen(s) + 1;
  1710.   return (sn->index);
  1711. }
  1712.  
  1713.  
  1714. static uint8 elf32_getinfo(struct Symbol *sym)
  1715. {
  1716.   uint8 type;
  1717.  
  1718.   switch (sym->info) {
  1719.     case SYMI_NOTYPE:
  1720.       type = STT_NOTYPE;  /* @@@ Is this allowed? */
  1721.       break;
  1722.     case SYMI_OBJECT:
  1723.       type = STT_OBJECT;
  1724.       break;
  1725.     case SYMI_FUNC:
  1726.       type = STT_FUNC;
  1727.       break;
  1728.     case SYMI_SECTION:
  1729.       ierror("elf32be_addsymlist(): STT_SECTION symbol detected");
  1730.       type = STT_SECTION;
  1731.       break;
  1732.     case SYMI_FILE:
  1733.       type = STT_FILE;
  1734.       break;
  1735.     default:
  1736.       ierror("elf32_getinfo(): Illegal symbol info: %d",(int)sym->info);
  1737.       break;
  1738.   }
  1739.   return (type);
  1740. }
  1741.  
  1742.  
  1743. static uint8 elf32_getbind(struct Symbol *sym)
  1744. {
  1745.   uint8 bind;
  1746.  
  1747.   switch (sym->bind) {
  1748.     case SYMB_LOCAL:
  1749.       bind = STB_LOCAL;
  1750.       break;
  1751.     case SYMB_GLOBAL:
  1752.       bind = STB_GLOBAL;
  1753.       break;
  1754.     case SYMB_WEAK:
  1755.       bind = STB_WEAK;
  1756.       break;
  1757.     default:
  1758.       ierror("elf32_getbind(): Illegal symbol binding: %d",(int)sym->bind);
  1759.       break;
  1760.   }
  1761.   return (bind);
  1762. }
  1763.  
  1764.  
  1765. static uint16 elf32_getshndx(struct Symbol *sym,uint8 symtype)
  1766. {
  1767.   uint16 shndx;
  1768.  
  1769.   switch (sym->type) {
  1770.     case SYM_UNDEF:
  1771.       shndx = SHN_UNDEF;
  1772.       break;
  1773.     case SYM_ABS:
  1774.       shndx = SHN_ABS;
  1775.       break;
  1776.     case SYM_RELOC:
  1777.       if (symtype > STT_FUNC)
  1778.         ierror("elf32_getshndx(): %s is relocatable, but not a "
  1779.                "function or object (type %d)",sym->name,(int)symtype);
  1780.       shndx = (uint16)sym->relsect->lnksec->index;
  1781.       break;
  1782.     case SYM_COMMON:
  1783.       shndx = SHN_COMMON;
  1784.       break;
  1785.     default:
  1786.       ierror("elf32_getshndx(): Illegal symbol type: %d",(int)sym->type);
  1787.       break;
  1788.   }
  1789.   return (shndx);
  1790. }
  1791.  
  1792.  
  1793. static void elf32_writesections(struct GlobalVars *gv,FILE *f)
  1794. /* write all linked sections */
  1795. {
  1796.   struct LinkedSection *ls = (struct LinkedSection *)gv->lnksec.first;
  1797.   struct LinkedSection *nextls;
  1798.  
  1799.   while (nextls = (struct LinkedSection *)ls->n.next) {
  1800.     if (!(ls->flags & SF_UNINITIALIZED))
  1801.       fwritex(f,ls->data,ls->size);
  1802.     ls = nextls;
  1803.   }
  1804. }
  1805.  
  1806.  
  1807. static void elf32_writestrtab(FILE *f,struct StrTabList *sl)
  1808. {
  1809.   struct StrTabNode *stn;
  1810.  
  1811.   while (stn = (struct StrTabNode *)remhead(&sl->l))
  1812.     fwritex(f,stn->str,strlen(stn->str)+1);
  1813. }
  1814.  
  1815.  
  1816. static void elf32_writesymtab(FILE *f,struct SymTabList *sl)
  1817. {
  1818.   struct SymbolNode *sym;
  1819.  
  1820.   while (sym = (struct SymbolNode *)remhead(&sl->l))
  1821.     fwritex(f,&sym->s,sizeof(struct Elf32_Sym));
  1822. }
  1823.  
  1824.  
  1825. static void elf32_writerelocs(struct GlobalVars *gv,FILE *f)
  1826. {
  1827.   struct RelaNode *rn;
  1828.  
  1829.   while (rn = (struct RelaNode *)remhead(&relalist))
  1830.     fwritex(f,&rn->r,gv->short_rel ? sizeof(struct Elf32_Rel) : 
  1831.                                      sizeof(struct Elf32_Rela));
  1832. }
  1833.  
  1834.  
  1835. #endif
  1836.